using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Media;
using BreakReminder.Properties;
using System.IO;

namespace BreakReminder
{
    public partial class Form1 : Form
    {
        DateTime nextTick;

        public Form1()
        {
            InitializeComponent();
            this.StartPosition = FormStartPosition.CenterScreen;
        }


        /// <summary>
        /// This is the form move event.  We are causing the form to not show up on the
        /// task bar when minimized.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Move(object sender, EventArgs e)
        {
            //This code causes the form to not show up on the task bar only in the tray.
            //NOTE there is now a form property that will allow you to keep the application
            //from every showing up in the task bar.
            if (this == null)
            { //This happen on create.
                return;
            }
            //If we are minimizing the form then hide it so it doesn't show up on the task bar
            if (this.WindowState == FormWindowState.Minimized)
            {
                Hide();
            }
            else
            {//any other windows state show it.
                Show();
            }

        }

        /// <summary>
        /// This is the context menu for the notify icon
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //If we don't minimize the window first we won't be able to close the window.
            this.WindowState = FormWindowState.Minimized;
            Close();
        }

        /// <summary>
        /// This is the notify Icon double click event when you click the tray icon
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void notifyIcon1_DoubleClick(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                Show();
                WindowState = FormWindowState.Normal;
            }

            // Activate the form.
            Activate();
            Focus();
        }

        private void buttonOK_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }

        private void setTimerInterval()
        {
            if (radioButtonInterval.Checked)
            {
                try
                {
                    timer1.Interval = Convert.ToInt32(Convert.ToDouble(textBoxInterval.Text) * 3600000);

                }
                catch (Exception)
                {
                    timer1.Enabled = false;
                }
            }
            else
            {
                DateTime now = DateTime.Now;
                for (int i = 0; i < ScheduledTimes.Count; i++)
                {
                    try
                    {
                        DateTime nextTime = DateTime.ParseExact(ScheduledTimes[i], "HH:mm", null);
                        if (now > nextTime && i < (ScheduledTimes.Count - 1)) continue;
                        if (i == (ScheduledTimes.Count - 1) && now > nextTime)
                        {
                            nextTime = DateTime.ParseExact(ScheduledTimes[0], "HH:mm", null).AddDays(1);
                        }
                        timer1.Interval = Convert.ToInt32(((TimeSpan)(nextTime - now)).TotalMilliseconds);
                        break;
                    }
                    catch (Exception)
                    {
                        timer1.Interval = int.MaxValue;
                    }
                }
            }
            nextTick = DateTime.Now.AddMilliseconds(timer1.Interval);
            timer1.Stop();
            timer1.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            setTimerInterval();
            notifyIcon1.ShowBalloonTip(3000, "time for break",
                " ",
                ToolTipIcon.Info);
            try
            {
                if (playSoundCheckBox.Checked)
                {
                    SoundPlayer simpleSound = null;
                    if (!internalSoundRadioButton.Checked)
                    {
                        if (File.Exists(soundFileNameTextBox.Text))
                        {
                            simpleSound = new SoundPlayer(soundFileNameTextBox.Text);
                        }
                        else
                        {
                            internalSoundRadioButton.Checked = true;
                            soundFileNameTextBox.Text = null;
                        }
                    }
                    if (internalSoundRadioButton.Checked)
                    {
                        simpleSound = new SoundPlayer(Resources.gimme_a_break);
                    }
                    simpleSound.Play();
                }
            }
            catch (Exception)
            {
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            InitializeScheduledTimes();
            textBoxInterval.Text = IsolatedStoreDataSource.Interval;
            radioButtonInterval.Checked = IsolatedStoreDataSource.UseInterval;
            radioButtonNotInterval.Checked = !IsolatedStoreDataSource.UseInterval;
            playSoundCheckBox.Checked = IsolatedStoreDataSource.IsPlaySound;
            internalSoundRadioButton.Checked = IsolatedStoreDataSource.IsInternalSound;
            externalSoundRadioButton.Checked = !internalSoundRadioButton.Checked;
            soundFileNameTextBox.Text = IsolatedStoreDataSource.SoundFile;
            comboBoxTime.DataSource = ScheduledTimes;
            comboBoxTime.Text = "hh:mm";
            radioButtonInterval_CheckedChanged(this, null);
            playSoundCheckBox_CheckedChanged(this, null);
            setTimerInterval();
            if (WindowState != FormWindowState.Minimized)
            {
                WindowState = FormWindowState.Minimized;
            }
            Hide();
        }

        void textBoxInterval_TextChanged(object sender, EventArgs e)
        {
            IsolatedStoreDataSource.Interval = textBoxInterval.Text;
        }

        void ScheduledTimes_ListChanged(object sender, ListChangedEventArgs e)
        {
            String[] sa = new String[ScheduledTimes.Count];
            ScheduledTimes.CopyTo(sa, 0);
            IsolatedStoreDataSource.ScheduledTimes = sa;
            setTimerInterval();
        }

        private void textBoxInterval_Click(object sender, EventArgs e)
        {
            textBoxInterval.SelectAll();
        }

        private void resetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            setTimerInterval();
        }

        private void textBoxInterval_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                setTimerInterval();
                buttonOK_Click(sender, e);
            }
        }

        private void radioButtonInterval_CheckedChanged(object sender, EventArgs e)
        {
            IsolatedStoreDataSource.UseInterval = radioButtonInterval.Checked;
            resetToolStripMenuItem.Visible = radioButtonInterval.Checked;
            textBoxInterval.ReadOnly = radioButtonNotInterval.Checked;
            comboBoxTime.Enabled = radioButtonNotInterval.Checked;
            buttonAddTime.Enabled = radioButtonNotInterval.Checked;
            buttonRemoveTime.Enabled = radioButtonNotInterval.Checked;
            setTimerInterval();
        }

        private void radiobuttonNotInterval_Click(object sender, EventArgs e)
        {
            comboBoxTime.Focus();
            comboBoxTime.SelectAll();
        }

        private void radiobuttonInterval_Click(object sender, EventArgs e)
        {
            textBoxInterval.Focus();
            textBoxInterval.SelectAll();
        }

        private void buttonAddTime_Click(object sender, EventArgs e)
        {
            DateTime res;
            if (!DateTime.TryParseExact(comboBoxTime.Text, "HH:mm", null, System.Globalization.DateTimeStyles.None, out res))
            {
                comboBoxTime.SelectAll();
                errorProvider1.SetError(comboBoxTime, "invalid time");
                return;
            }

            foreach (String s in ScheduledTimes)
            {
                if (s.CompareTo(comboBoxTime.Text) == 0)
                {
                    break;
                }
                else if (s.CompareTo(comboBoxTime.Text) > 0)
                {
                    ScheduledTimes.Insert(ScheduledTimes.IndexOf(s), comboBoxTime.Text);
                    break;
                }
            }
            if (ScheduledTimes.Count > 0 && comboBoxTime.Text.CompareTo(ScheduledTimes[ScheduledTimes.Count - 1]) > 0)
            {
                ScheduledTimes.Add(comboBoxTime.Text);
            }
        }

        BindingList<String> ScheduledTimes;
        void InitializeScheduledTimes()
        {
            ScheduledTimes = new BindingList<string>();
            foreach (String s in IsolatedStoreDataSource.ScheduledTimes)
            {
                ScheduledTimes.Add(s);
            }
            ScheduledTimes.ListChanged += new ListChangedEventHandler(ScheduledTimes_ListChanged);
        }

        private void buttonRemoveTime_Click(object sender, EventArgs e)
        {
            ScheduledTimes.Remove((String)comboBoxTime.SelectedValue);
        }

        private void comboBoxTime_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter) buttonAddTime_Click(sender, e);
        }

        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
        {
            messageToolStripMenuItem.Text = "Next Break@" + nextTick.ToShortTimeString();
        }

        private void textBoxInterval_Validating(object sender, CancelEventArgs e)
        {
            Decimal dec;
            if (!Decimal.TryParse(textBoxInterval.Text, out dec) || dec.CompareTo(0.001m) < 0)
            {
                e.Cancel = true;
                textBoxInterval.SelectAll();
                errorProvider1.SetError(textBoxInterval, "invalid number or number less than 0.001");
            }
        }

        private void Input_Validated(object sender, EventArgs e)
        {
            errorProvider1.SetError((Control)sender, "");
        }

        private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            this.soundFileNameTextBox.Text = openFileDialog1.FileName;
        }

        private void playSoundCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            IsolatedStoreDataSource.IsPlaySound = playSoundCheckBox.Checked;
            internalSoundRadioButton.Enabled = externalSoundRadioButton.Enabled = soundFileNameTextBox.Enabled = fileBrowseButton.Enabled = playSoundCheckBox.Checked;
        }

        private void fileBrowseButton_Click(object sender, EventArgs e)
        {
            openFileDialog1.ShowDialog();
        }

        private void internalSoundRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            IsolatedStoreDataSource.IsInternalSound = internalSoundRadioButton.Checked;
        }

        private void soundFileNameTextBox_TextChanged(object sender, EventArgs e)
        {
            IsolatedStoreDataSource.SoundFile = soundFileNameTextBox.Text;
        }

        private void notifyIcon1_MouseMove(object sender, MouseEventArgs e)
        {
            notifyIcon1.Text = "Next Break@" + nextTick.ToShortTimeString();
        }
    }

}